package seatiger.tomcat.catalina.logger;

import seatiger.tomcat.catalina.Lifecycle;
import seatiger.tomcat.catalina.LifecycleException;
import seatiger.tomcat.catalina.LifecycleListener;
import seatiger.tomcat.catalina.util.LifecycleSupport;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;

/**
 * Logger 接口，将日志输出到文件中
 */
public class FileLogger extends LoggerBase implements Lifecycle {

    private String date = "";

    private PrintWriter writer;
    //记录日志是否需要加上时间
    private boolean timestamp = false;

    /**
     * 日志目录
     */
    private String directory = "logs";

    private String prefix = "catalina.";
    private String suffix = ".log";

    private LifecycleSupport lifecycle = new LifecycleSupport(this);

    private volatile boolean started = false;

    public boolean isTimestamp() {
        return timestamp;
    }

    public void setTimestamp(boolean timestamp) {
        this.timestamp = timestamp;
    }

    public String getDirectory() {
        return directory;
    }

    public void setDirectory(String directory) {
        this.directory = directory;
    }

    public String getPrefix() {
        return prefix;
    }

    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    public String getSuffix() {
        return suffix;
    }

    public void setSuffix(String suffix) {
        this.suffix = suffix;
    }

    @Override
    public void log(String message) {
        LocalDateTime dateTime = LocalDateTime.now();
        LocalDate localDate = dateTime.toLocalDate();
        LocalTime time = dateTime.toLocalTime();
        //创建新的文件
        String tsData = String.valueOf(localDate);
        if (!date.equals(tsData)){
            synchronized (this){
                if (!date.equals(tsData)){
                    close();
                    date = tsData;
                    open();
                }
            }
        }
        if (writer != null){
            if (timestamp){
                writer.println(time + " " + message);
            }else{
                writer.println(message);
            }
        }
    }

    private void close(){
        if (writer == null){
            return;
        }
        writer.flush();
        writer.close();
        writer = null;
        date = "";
    }

    private void open(){
        File dir = new File(directory);
        if (!dir.isAbsolute()){
            dir = new File(System.getProperty("catalina.base"),directory);
        }
        dir.mkdirs();
        try {
            String pathname = dir.getAbsolutePath() + File.separator +
                    prefix + date + suffix;
            writer = new PrintWriter(new FileWriter(pathname,true),true);
        }catch (IOException e){
            writer = null;
        }
    }

    @Override
    public void addLifecycleListener(LifecycleListener listener) {
        lifecycle.addLifecycleListener(listener);
    }

    @Override
    public List<LifecycleListener> findLifecycleListeners() {
        return lifecycle.findLifecycleListeners();
    }

    @Override
    public void removeLifecycleListener(LifecycleListener listener) {
        lifecycle.removeLifecycleListener(listener);
    }

    @Override
    public void start() throws LifecycleException {
        if (started)
            throw new LifecycleException("fileLogger.alreadyStarted");
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        started = true;
    }

    @Override
    public void stop() throws LifecycleException {
        if (!started){
            throw new LifecycleException("fileLogger.notStarted");
        }
        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
        started = false;
        close();
    }
}
